package cn.lijiajia3515.cairo.captcha.image.graph;

import cn.hutool.core.util.RandomUtil;
import cn.lijiajia3515.cairo.captcha.image.ImageCaptcha;
import org.springframework.http.MediaType;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * png 画验证码图处理器
 */
public class PngGraphCaptchaImageHandler extends AbstractGraphImageCaptchaHandler {

	public PngGraphCaptchaImageHandler() {
		super();
	}

	public PngGraphCaptchaImageHandler(int[][] color, String[] fontNames) {
		super(color, fontNames);
	}

	@Override
	public ImageCaptcha.ImageCaptchaDetail getDetail(GraphImageArgs args) {
		BufferedImage bImage = graphImage(args);
		try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
			ImageIO.write(bImage, "png", out);
			out.flush();
			return ImageCaptcha.ImageCaptchaDetail.builder().bytes(out.toByteArray()).mediaType(MediaType.IMAGE_PNG).build();
		} catch (IOException e) {
			throw new RuntimeException("验证码生成失败");
		}
	}

	public BufferedImage graphImage(GraphImageArgs args) {
		String str = args.getImageStr();
		int width = args.getWidth();
		int height = args.getHeight();
		// 画布
		BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		// 画笔
		Graphics2D g2d = (Graphics2D) bi.getGraphics();
		// 填充背景
		g2d.setColor(Color.WHITE);
		g2d.fillRect(0, 0, width, height);

		// 抗锯齿
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		// 画干扰圆
		drawOval(RandomUtil.randomInt(3, 6), width, height, g2d);
		// 画干扰线
		g2d.setStroke(new BasicStroke(1.2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
		drawBesselLine(RandomUtil.randomInt(1, 3), null, width, height, g2d);

		// 画字符串
		g2d.setFont(font());

		int fW = (width - 12) / str.length(); // 字体宽度
		FontMetrics fontMetrics = g2d.getFontMetrics();
		// 字符的左右边距

		int fSp = (fW - (int) fontMetrics.getStringBounds("W", g2d).getWidth()) / 2;
		for (int i = 0; i < str.length(); i++) {
			g2d.setColor(color());
			int fX = i * fW + fSp + 6;
			// 字符高度坐标
			int fY = height - (int) (((height - fontMetrics.getStringBounds(String.valueOf(str.charAt(i)), g2d).getHeight())) / 2) - 8;
			g2d.drawString(String.valueOf(str.charAt(i)), fX, fY);
		}

		g2d.dispose();
		return bi;
	}
}
